//
// Created by mio on 25-4-11.
//

#ifndef EVENTLOOP_H
#define EVENTLOOP_H


#include <vector>

#include "TaskScheduler.h"

/**
 * @brief EventLoop 类，负责创建和管理一个或多个 TaskScheduler 实例（通常在单独的线程中运行）。
 * 它作为访问底层 TaskScheduler 的入口点，并提供了线程管理功能。
 * 实现了 "one loop per thread" 的模型。
 */
class EventLoop
{
public:
    EventLoop(uint32_t num_threads = 1);
    ~EventLoop();
    // 删除拷贝构造函数和拷贝赋值运算符，防止 EventLoop 对象被复制
    EventLoop(const EventLoop& other) = delete;
    EventLoop& operator = (const EventLoop& other) = delete;

    /**
     * @brief 获取一个 TaskScheduler 实例的智能指针。
     * 如果有多个 TaskScheduler 实例（多线程），则采用轮询 (Round-Robin) 方式返回下一个实例。
     * 主要用于将新的连接 (Channel) 分配给不同的事件循环线程处理。
     * @return 一个 TaskScheduler 的 shared_ptr。如果 EventLoop 未初始化，可能返回 nullptr (虽然当前实现不会)。
     */
    TaskSchedulerPtr GetTaskScheduler();
    // --- 以下接口似乎总是操作第一个 TaskScheduler (task_schedulers_[0]) ---
    // --- 这通常用于主线程或专门的 Acceptor 线程与 EventLoop 交互 ---

    /**
     * @brief 添加一个定时器任务到 *第一个* TaskScheduler。
     * @param event 定时器回调。
     * @param mesc 间隔或延迟（毫秒）。
     * @return 定时器 ID。
     */
    TimerId AddTimer(const TimerEvent& event, uint32_t mesc);
    /**
     * @brief 从 *第一个* TaskScheduler 移除一个定时器。
     * @param timerId 要移除的定时器 ID。
     */
    void RemoveTimer(TimerId timerId);
    /* 两个Channel接口供后续的单线程Acceptor调用 */
    void UpdateChannel(ChannelPtr channel);
    void RemoveChannel(ChannelPtr channel);
    // --- 线程和循环管理 ---

    /**
     * @brief （内部方法）创建并启动所有 TaskScheduler 线程。
     * 通常不应由外部直接调用，已在构造函数中调用。
     */
    void Loop();
    /**
     * @brief 停止所有事件循环线程并等待它们结束。
     */
    void Quit();

private:
    uint32_t num_threads_ = 1;  // 要创建的事件循环线程数
    uint32_t index_ = 1;        // 用于 GetTaskScheduler() 轮询的当前索引 (初始化为0更常见)
    // 存储所有创建的 TaskScheduler 实例的智能指针
    std::vector<std::shared_ptr<TaskScheduler>> task_schedulers_;
    // 存储所有创建的事件循环线程对象的智能指针
    std::vector<std::shared_ptr<std::thread>> threads_;
};

#endif //EVENTLOOP_H
